package managedBean.TX.SABM;

import entity.Outlet;
import session.TX.StakeholderAccountSBRemote;
import session.TX.TierManagementSBRemote;
import entity.Stakeholder;
import entity.StakeholderFood;
import entity.StakeholderTier;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import java.util.Properties;
import javax.annotation.Resource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.faces.application.FacesMessage;  
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;  
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperRunManager;

@ManagedBean(name = "stakeholderAccountsManagerBean")
@SessionScoped
public class StakeholderMB {
    @Resource(name = "food")
    private DataSource food;


    @EJB
     StakeholderAccountSBRemote stakeholderAccountBean;
     
     Long stakeholderId;
     String stakeholderName;
     Integer loyaltyPoints;
     String stakeholderTier;
     private String statusMessage;
     private Integer month1;
     private Integer year;
     private String address, postalCode, categoryDescription, phoneNo;
     Stakeholder selectedStakeholder;
     private String purchaseBI;
     
     
     
     @EJB
     TierManagementSBRemote tierManagementBean;

    public StakeholderMB() {}
    


 public void generateReport(ActionEvent event) {
        try
        {   
            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
            
            String strSQL = "SELECT NAME AS STAKEHOLDER_NAME, ADDRESS AS STAKEHOLDER_ADDRESS, LOYALTYPOINTS AS STAKEHOLDER_LOYALTYPOINTS, POSTALCODE AS STAKEHOLDER_POSTALCODE, PHONENO AS STAKEHOLDER_PHONENO"
                    + ", STAKEHOLDERTIER_NAME AS STAKEHOLDER_STAKEHOLDERTIER_NAME FROM STAKEHOLDER";
                    
                   
            ResultSet rsAddresses = food.getConnection().prepareStatement(strSQL).executeQuery();
            JRResultSetDataSource jrResultSetDataSource = new JRResultSetDataSource(rsAddresses);
            InputStream reportStream = ((HttpSession)ec.getSession(true)).getServletContext().getResourceAsStream("/jasperreports/showAllStakeholder.jasper");
            
            ec.setResponseContentType("application/pdf");
            OutputStream outputStream = ec.getResponseOutputStream(); 
            JasperRunManager.runReportToPdfStream(reportStream, outputStream, new HashMap(), jrResultSetDataSource);
            outputStream.flush();
            outputStream.close();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
    
    public void generateSalesReport (ActionEvent event) {
        try
        {
            stakeholderId = (Long)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholderId");
            
            Calendar lowerBound = Calendar.getInstance();
            Integer month = getMonth1() - 1;  
            lowerBound.set(getYear(), month, 1);
   
            Calendar upperBound = Calendar.getInstance();
            int lastDayOfMonth = lowerBound.getActualMaximum(Calendar.DAY_OF_MONTH);  
            upperBound.set(getYear(), month, lastDayOfMonth);

            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
            
            String lowerBound_string = "'" + getYear() + "-" + month1 + "-" + lowerBound.get(Calendar.DATE) + " 00:00:00.0'";
            String upperBound_string = "'" + getYear() + "-" + month1 + "-" + upperBound.get(Calendar.DATE) + " 00:00:00.0'";
            
            String strSQL = "SELECT TIME_STAMP AS PURCHASEDITEM_TIME_STAMP, QUANTITY AS PURCHASEDITEM_QUANTITY, ITEM_NAME AS PURCHASEDITEM_ITEM_NAME, SUBTOTAL AS PURCHASEDITEM_SUBTOTAL, OUTLET_NAME AS PURCHASEDITEM_OUTLET_NAME FROM PURCHASEDITEM"
                   +  " WHERE TIME_STAMP BETWEEN " + lowerBound_string + " AND " + upperBound_string + " AND STAKEHOLDERID = " + stakeholderId;
            
            
            ResultSet rsAddresses = food.getConnection().prepareStatement(strSQL).executeQuery();
            JRResultSetDataSource jrResultSetDataSource = new JRResultSetDataSource(rsAddresses);
            InputStream reportStream = ((HttpSession)ec.getSession(true)).getServletContext().getResourceAsStream("/jasperreports/salesReport.jasper");
            
            ec.setResponseContentType("application/pdf");
            OutputStream outputStream = ec.getResponseOutputStream(); 
            
            JasperRunManager.runReportToPdfStream(reportStream, outputStream, new HashMap(), jrResultSetDataSource);
            
            outputStream.flush();
            outputStream.close();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
    
    public void generateStakeholderBill (ActionEvent event) {
            
        try
        {
            Calendar lowerBound = Calendar.getInstance();
            Integer month = getMonth1() - 1;  
            lowerBound.set(getYear(), month, 1);
   
            Calendar upperBound = Calendar.getInstance();
            int lastDayOfMonth = lowerBound.getActualMaximum(Calendar.DAY_OF_MONTH);  
            upperBound.set(getYear(), month, lastDayOfMonth);

            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
            
            String lowerBound_string = "'" + getYear() + "-" + getMonth1() + "-" + lowerBound.get(Calendar.DATE) +"'";
            String upperBound_string = "'" + getYear() + "-" + getMonth1() + "-" + upperBound.get(Calendar.DATE) +"'";
            
            String strSQL = "SELECT B.STAKEHOLDERNAME AS STAKEHOLDERBILL_STAKEHOLDERNAME, B.BILLADVERTISING AS STAKEHOLDERBILL_BILLADVERTISING, "
                    + "B.BILLMARKETINTELLIGENCE AS STAKEHOLDERBILL_BILLMARKETINTELLIGENCE, B.BILLSUBSCRIPTION AS STAKEHOLDERBILL_BILLSUBSCRIPTION, B.REINBURSEMENT AS STAKEHOLDERBILL_REINBURSEMENT, "
                    + "B.SUBTOTAL AS STAKEHOLDERBILL_SUBTOTAL, B.BILLDATE AS STAKEHOLDERBILL_BILLDATE, B.HASPAID AS STAKEHOLDERBILL_HASPAID"
                    + " FROM STAKEHOLDERBILL B, STAKEHOLDER S WHERE (B.BILLDATE BETWEEN " + lowerBound_string + " AND " + upperBound_string +") AND (B.STAKEHOLDERNAME = S.NAME) "
                    + " AND S.STAKEHOLDERTIER_NAME = '" + stakeholderTier + "'";
            
             
            ResultSet rsAddresses = food.getConnection().prepareStatement(strSQL).executeQuery();
            JRResultSetDataSource jrResultSetDataSource = new JRResultSetDataSource(rsAddresses);
            InputStream reportStream = ((HttpSession)ec.getSession(true)).getServletContext().getResourceAsStream("/jasperreports/stakeholderBill.jasper");
            
            ec.setResponseContentType("application/pdf");
            OutputStream outputStream = ec.getResponseOutputStream(); 
            
            JasperRunManager.runReportToPdfStream(reportStream, outputStream, new HashMap(), jrResultSetDataSource);
            
            outputStream.flush();
            outputStream.close();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
    
    public void generateRewardRecord (ActionEvent event) {
            stakeholderId = (Long)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholderId");
            Stakeholder s = stakeholderAccountBean.findStakeholder(stakeholderId);
            String stakeholderName = s.getName();
      
        try
        {
            Calendar lowerBound = Calendar.getInstance();
            Integer month = getMonth1() - 1;  
            lowerBound.set(getYear(), month, 1);
   
            Calendar upperBound = Calendar.getInstance();
            int lastDayOfMonth = lowerBound.getActualMaximum(Calendar.DAY_OF_MONTH);  
            upperBound.set(getYear(), month, lastDayOfMonth);

            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
            
            String lowerBound_string = "'" + getYear() + "-" + month1 + "-" + lowerBound.get(Calendar.DATE) + " 00:00:00.0'";
            String upperBound_string = "'" + getYear() + "-" + month1 + "-" + upperBound.get(Calendar.DATE) + " 00:00:00.0'";
            
            String strSQL = "SELECT PURCHASEDATE AS REWARDVOUCHER_PURCHASEDATE, REDEEMED AS REWARDVOUCHER_REDEEMED, REDEMPTIONDATE AS REWARDVOUCHER_REDEMPTIONDATE, "
                    + "REWARD_COST AS REWARDVOUCHER_REWARD_COST, REWARD_NAME AS REWARDVOUCHER_REWARD_NAME FROM REWARDVOUCHER WHERE STAKEHOLDER = '" + stakeholderName + "' AND REDEMPTIONDATE BETWEEN " + lowerBound_string + " AND " + upperBound_string +"";
                
            ResultSet rsAddresses = food.getConnection().prepareStatement(strSQL).executeQuery();
            JRResultSetDataSource jrResultSetDataSource = new JRResultSetDataSource(rsAddresses);
            InputStream reportStream = ((HttpSession)ec.getSession(true)).getServletContext().getResourceAsStream("/jasperreports/rewardRecords.jasper");
            
            ec.setResponseContentType("application/pdf");
            OutputStream outputStream = ec.getResponseOutputStream(); 
            
            JasperRunManager.runReportToPdfStream(reportStream, outputStream, new HashMap(), jrResultSetDataSource);
            
            outputStream.flush();
            outputStream.close();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }


      
    public void createStakeholder(ActionEvent event) {
                     
        //Stakeholder
        String stakeholder_Name = String.valueOf(getStakeholderName());
        Integer loyalty_points = Integer.valueOf(getLoyaltyPoints());
       
        String stakeholdertier = String.valueOf(getStakeholderTier());
  
        
        boolean check = stakeholderAccountBean.createStakeholder(
             stakeholder_Name, getAddress(), getPhoneNo(), getPostalCode(), getCategoryDescription(),
            
             loyalty_points,
             stakeholdertier);
        
        
        
    if (check == true) {
            statusMessage = (stakeholder_Name + " created successfully");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Result: " + getStatusMessage(), ""));

    } else {
            statusMessage = (stakeholder_Name + " already exists");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Result: " + getStatusMessage(), ""));
        }
        
    }
    
    
   public List<StakeholderTier> getAvailableTier(){
        return tierManagementBean.getAllTiers();
    }

    
    public List<Stakeholder> getAllStakeholders() {
        return stakeholderAccountBean.getAllStakeholders();
    }
    
    public List<Stakeholder> getBIStakeholder(String name){
        return stakeholderAccountBean.getSpecificStakeholders(name);
    }
    
    public List<Stakeholder> getSpecificStakeholders(ActionEvent event) {
        String name = String.valueOf(getStakeholderName());
        return stakeholderAccountBean.getSpecificStakeholders(name);
    }
    
    public void deleteStakeholder(Stakeholder stakeholder) {

        
        String s = stakeholder.getName();
        
        boolean check = stakeholderAccountBean.deleteStakeholder(s);
        if (check == true) {
            statusMessage = (s + " deleted successfully");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Result: " + getStatusMessage(), ""));
        } else {
            statusMessage = (s + " got outstanding bill therefore it cannot be deleted");
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Result: " + getStatusMessage(), ""));
        }
        
    }
    
    public void changeStakeholderTier() {
        System.out.println("Stakeholder: " + this.stakeholderName);
        System.out.println("Tier to Change: " + this.stakeholderTier);
        stakeholderAccountBean.changeStakeholderTier(this.stakeholderTier, this.stakeholderName);
        setStatusMessage(stakeholderName + " changed successfully to this tier: " + stakeholderTier);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Result: " + getStatusMessage(), ""));
    }
    
    public boolean changeStakeholderBI(){
        return stakeholderAccountBean.changeStakeholderBI(getPurchaseBI(), stakeholderName);
    }
    
    public List<StakeholderTier> getAllTiers() {
        return getTierManagementBean().getAllTiers();
    }
    
    public List<String> getNamesOfAllTiers() {
        List<String> returnList = new ArrayList<String>();
        
        
        for(Object o : tierManagementBean.getAllTiers()){
            StakeholderTier tierEntity = (StakeholderTier)o;
            returnList.add(tierEntity.getName());
        }
        
        return returnList;
        
    }
    
    public List<String> getNamesOfAllStakeholders() {
        List<String> returnList = new ArrayList<String>();
        
        for(Object o : stakeholderAccountBean.getAllStakeholders()){
            Stakeholder stakeholderEntity = (Stakeholder)o;
            returnList.add(stakeholderEntity.getName());
        }
        
        return returnList;
        
    }
    
    public List<String> getNamesOfSpecificStakeholders(String name) {
        List<String> returnList = new ArrayList<String>();
        System.out.println("test" + name);
        
        for(Object o : stakeholderAccountBean.getSpecificStakeholders(name)){
            Stakeholder stakeholderEntity = (Stakeholder)o;
            returnList.add(stakeholderEntity.getName());
        }
        
        return returnList;
        
    }


    /**
     * @return the stakeholderAccountBean
     */
    public StakeholderAccountSBRemote getStakeholderAccountBean() {
        return stakeholderAccountBean;
    }

    /**
     * @param stakeholderAccountBean the stakeholderAccountBean to set
     */
    public void setStakeholderAccountBean(StakeholderAccountSBRemote stakeholderAccountBean) {
        this.stakeholderAccountBean = stakeholderAccountBean;
    }

    /**
     * @return the stakeholderName
     */
    public String getStakeholderName() {
        return stakeholderName;
    }

    /**
     * @param stakeholderName the stakeholderName to set
     */
    public void setStakeholderName(String stakeholderName) {
        this.stakeholderName = stakeholderName;
    }

    /**
     * @return the loyaltyPoints
     */
    public Integer getLoyaltyPoints() {
        return loyaltyPoints;
    }

    /**
     * @param loyaltyPoints the loyaltyPoints to set
     */
    public void setLoyaltyPoints(Integer loyaltyPoints) {
        this.loyaltyPoints = loyaltyPoints;
    }

    /**
     * @return the stakeholderTier
     */
    public String getStakeholderTier() {
        return stakeholderTier;
    }

    /**
     * @param stakeholderTier the stakeholderTier to set
     */
    public void setStakeholderTier(String stakeholderTier) {
        this.stakeholderTier = stakeholderTier;
    }

    /**
     * @return the tierManagementBean
     */
    public TierManagementSBRemote getTierManagementBean() {
        return tierManagementBean;
    }

    /**
     * @param tierManagementBean the tierManagementBean to set
     */
    public void setTierManagementBean(TierManagementSBRemote tierManagementBean) {
        this.tierManagementBean = tierManagementBean;
    }

    /**
     * @return the statusMessage
     */
    public String getStatusMessage() {
        return statusMessage;
    }

    /**
     * @param statusMessage the statusMessage to set
     */
    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }


        /**
     * @return the selectedStakeholder
     */
    public Stakeholder getSelectedStakeholder() {
        return selectedStakeholder;
    }

    /**
     * @param selectedStakeholder the selectedStakeholder to set
     */
    public void setSelectedStakeholder(Stakeholder selectedStakeholder) {
        this.selectedStakeholder = selectedStakeholder;
        System.out.println(">>>>>> "+this.selectedStakeholder.getName());
    }

    /**
     * @return the month1
     */
    public Integer getMonth1() {
        return month1;
    }

    /**
     * @param month1 the month1 to set
     */
    public void setMonth1(Integer month1) {
        this.month1 = month1;
    }

    /**
     * @return the year
     */
    public Integer getYear() {
        return year;
    }

    /**
     * @param year the year to set
     */
    public void setYear(Integer year) {
        this.year = year;
    }

    /**
     * @return the address
     */
    public String getAddress() {
        return address;
    }

    /**
     * @param address the address to set
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     * @return the phoneNo
     */
    public String getPhoneNo() {
        return phoneNo;
    }

    /**
     * @param phoneNo the phoneNo to set
     */
    public void setPhoneNo(String phoneNo) {
        this.phoneNo = phoneNo;
    }

    /**
     * @return the postalCode
     */
    public String getPostalCode() {
        return postalCode;
    }

    /**
     * @param postalCode the postalCode to set
     */
    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    /**
     * @return the categoryDescription
     */
    public String getCategoryDescription() {
        return categoryDescription;
    }

    /**
     * @param categoryDescription the categoryDescription to set
     */
    public void setCategoryDescription(String categoryDescription) {
        this.categoryDescription = categoryDescription;
    }

    /**
     * @return the purchaseBI
     */
    public String getPurchaseBI() {
        return purchaseBI;
    }

    /**
     * @param purchaseBI the purchaseBI to set
     */
    public void setPurchaseBI(String purchaseBI) {
        this.purchaseBI = purchaseBI;
    }


   



 }  
